// -----------------------------
// Author: 		Dhaenens Gert	
// Creation: 	2/12/2015 10:46:27 PM				
// -----------------------------

#include "CWindow.h"

#include "WindowEventHandler.h"

#include <wrl\client.h>

struct __declspec(uuid("45D64A29-A63E-4CB6-B498-5781D298CB4F")) __declspec(novtable)
ICoreWindowInterop : IUnknown
{
	virtual HRESULT __stdcall get_WindowHandle(HWND * hwnd) = 0;
};

HWND GetNativeHandle(CoreWindow^ window)
{
	Microsoft::WRL::ComPtr<ICoreWindowInterop> interop;
	HRESULT hr = reinterpret_cast<IUnknown*>(window)->QueryInterface(interop.GetAddressOf());
	if (FAILED(hr))
		return NULL;

	HWND hWindow = NULL;
	hr = interop->get_WindowHandle(&hWindow);
	if (FAILED(hr))
		return NULL;

	return hWindow;
}

namespace Flow
{

	CWindow::CWindow()
		: m_hWindow(NULL)
		, m_Width(0)
		, m_Height(0)
	{
	}

	CWindow::~CWindow()
	{
	}

	void CWindow::Release()
	{
		delete this;
	}

	Bool CWindow::Initialize(const GameConfig& config)
	{
		// Get the Core Window
		CoreWindow^ cxWindow = CoreWindow::GetForCurrentThread();
		m_hWindow = GetNativeHandle(cxWindow);
		
		// Register the Window Event Handler
		WindowEventHandler::RegisterEvents(cxWindow);
		WindowEventHandler::IsAlive = true;
		WindowEventHandler::IsVisible = true;

		// Get the Bounds
		Rect r = cxWindow->Bounds;

		m_Width = r.Width;
		m_Height = r.Height;

		return true;
	}
	void CWindow::Close()
	{
		CoreWindow^ cxWindow = CoreWindow::GetForCurrentThread();
		cxWindow->Close();
	}

	Bool CWindow::HandleMessages(ProcessOption::Enum type) const
	{
		CoreProcessEventsOption option;
		switch (type)
		{
		case Flow::ProcessOption::ProcessOne:
			option = CoreProcessEventsOption::ProcessOneIfPresent;
			break;
		case Flow::ProcessOption::ProcessOneAndAll:
			option = CoreProcessEventsOption::ProcessOneAndAllPending;
			break;
		case Flow::ProcessOption::ProcessAll:
			option = CoreProcessEventsOption::ProcessAllIfPresent;
			break;
		}

		WindowEventHandler::Dispatch(option);

		return false;
	}

	Bool CWindow::IsAlive() const
	{
		return WindowEventHandler::IsAlive;
	}
	Bool CWindow::IsVisible() const
	{
		return WindowEventHandler::IsVisible;
	}

	HWND CWindow::GetHandle() const
	{
		return m_hWindow;
	}
	UInt32 CWindow::GetWidth() const
	{
		return m_Width;
	}
	UInt32 CWindow::GetHeight() const
	{
		return m_Height;
	}

}



